package com.hanshg.cherry.controller;

import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.hanshg.cherry.base.result.PageTableRequest;
import com.hanshg.cherry.base.result.ResponseCode;
import com.hanshg.cherry.base.result.Results;
import com.hanshg.cherry.config.target.Logger;
import com.hanshg.cherry.dto.UserDto;
import com.hanshg.cherry.model.SysUser;
import com.hanshg.cherry.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.WebRequest;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author 柠檬水
 */
@Controller
@RequestMapping("user")
@Slf4j
@Api(tags = "用户控制层")
public class UserController {

    @Autowired
    private UserService userService;

    /**
     * 用户
     *
     * @param username 用户名
     * @return {@link SysUser}
     */
    @GetMapping("/{username}")
    @ResponseBody
    @ApiOperation(value = "获取用户信息")
    @ApiOperationSupport(author = "柠檬水 cherryok@126.com")
    public SysUser user(@PathVariable String username) {
        log.info("UserController.user():param (username=" + username + ")");
        return userService.getUser(username);
    }

    /**
     * 让用户
     *
     * @param page 页面
     * @return {@link Results<SysUser>}
     */
    @GetMapping("/list")
    @ResponseBody
    @PreAuthorize("hasAuthority('sys:user:query')")
    @ApiOperation(value = "分页获取用户信息", notes = "分页获取用户信息")
    @ApiOperationSupport(author = "柠檬水 cherryok@126.com")
    @ApiImplicitParam(name = "page", value = "分页查询实体类")
    @Logger(value = "用户查询",type = 1)
    public Results<SysUser> getUsers(PageTableRequest page) {
        log.info("UserController.getUsersPage():param (page=" + page + ")");
        page.countOffset();//计算
        return userService.getAllUserByPage(page.getOffset(), page.getLimit());
    }

    /**
     * 添加用户
     *
     * @param model 模型
     * @return {@link String}
     */
    @GetMapping("/add")
    @PreAuthorize("hasAuthority('sys:user:add')")
    @ApiOperationSupport(author = "柠檬水 cherryok@126.com")
    @ApiOperation(value = "用户新增页面", notes = "跳转到新增用户信息页面")
    @Logger(value = "新增用户",type = 2)
    public String addUser(Model model) {
        log.info("UserController.addUsers():param (" + model + ")");
        model.addAttribute("sysUser", new SysUser());
        return "user/user-add";
    }

    /**
     * 保存用户
     *
     * @param userDto 用户dto
     * @param roleId  角色id
     * @return {@link Results<SysUser>}
     */
    @PostMapping("/add")
    @ResponseBody
    @PreAuthorize("hasAuthority('sys:user:add')")
    @ApiOperationSupport(author = "柠檬水 cherryok@126.com")
    @ApiOperation(value = "保存用户信息", notes = "保存新增的用户信息")
    public Results<SysUser> saveUser(UserDto userDto, Long roleId) {
        log.info("UserController.saveUsers():param (" + userDto + ")");
        SysUser sysUser = null;
        sysUser = userService.getUser(userDto.getUsername());
        if (sysUser != null && !(sysUser.getId().equals(userDto.getId()))) {
            return Results.failure(ResponseCode.USERNAME_REPEAT.getCode(), ResponseCode.USERNAME_REPEAT.getMessage());
        }
        sysUser = userService.getUserByPhone(userDto.getTelephone());
        if (sysUser != null && !(sysUser.getId().equals(userDto.getId()))) {
            return Results.failure(ResponseCode.PHONE_REPEAT.getCode(), ResponseCode.PHONE_REPEAT.getMessage());
        }
//        sysUser = userService.getUserByEmail(userDto.getEmail());
//        if(sysUser != null && !(sysUser.getId().equals(userDto.getId()))){
//            return Results.failure(ResponseCode.EMAIL_REPEAT.getCode(),ResponseCode.EMAIL_REPEAT.getMessage());
//        }

        userDto.setStatus(1);
        //密码加密
        userDto.setPassword(new BCryptPasswordEncoder().encode(userDto.getPassword().trim()));
        return userService.save(userDto, roleId);
    }

    /**
     * 获取用户
     *
     * @param model   模型
     * @param sysUser 系统用户
     * @return {@link String}
     */
    @GetMapping("/info")
    @ApiOperation(value = "个人信息页面", notes = "跳转到个人信息查看页面")
    @ApiImplicitParam(name = "user", value = "用户实体类", dataType = "SysUser")
    @ApiOperationSupport(author = "柠檬水 cherryok@126.com")
    @Logger(value = "查询个人",type = 2)
    public String getUser(Model model, SysUser sysUser) {
        log.info("UserController.getUser():param (" + model + ")");
        model.addAttribute(userService.getUserById(sysUser.getId()));
        return "user/user-info";
    }

    /**
     * 处理日期转换
     */
    String pattern = "yyyy-MM-dd";
    @InitBinder
    public void initBinder(WebDataBinder binder, WebRequest request) {
        binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat(pattern), true));
    }

    /**
     * 编辑用户
     *
     * @param model   模型
     * @param sysUser 系统用户
     * @return {@link String}
     */
    @GetMapping("/edit")
    @ApiOperation(value = "用户编辑页面", notes = "跳转到用户信息编辑页面")
    @ApiImplicitParam(name = "user", value = "用户实体类", dataType = "SysUser")
    @ApiOperationSupport(author = "柠檬水 cherryok@126.com")
    @PreAuthorize("hasAuthority('sys:user:edit')")
    @Logger(value = "编辑用户",type = 2)
    public String editUser(Model model, SysUser sysUser) {
        log.info("UserController.editUser():param (" + model + ")");
        model.addAttribute(userService.getUserById(sysUser.getId()));
        return "user/user-edit";
    }

    /**
     * 编辑用户
     *
     * @param userDto 用户dto
     * @param roleId  角色id
     * @return {@link Results<SysUser>}
     */
    @PostMapping("/edit")
    @ResponseBody
    @PreAuthorize("hasAuthority('sys:user:edit')")
    @ApiOperation(value = "保存用户信息", notes = "保存编辑完的用户信息")
    @ApiOperationSupport(author = "柠檬水 cherryok@126.com")
    public Results<SysUser> editUser(UserDto userDto, Long roleId) {
        log.info("UserController.editUsers():param (" + userDto + ")");

        SysUser sysUser = null;
        sysUser = userService.getUser(userDto.getUsername());
        if (sysUser != null && !(sysUser.getId().equals(userDto.getId()))) {
            return Results.failure(ResponseCode.USERNAME_REPEAT.getCode(), ResponseCode.USERNAME_REPEAT.getMessage());
        }
        sysUser = userService.getUserByPhone(userDto.getTelephone());
        if (sysUser != null && !(sysUser.getId().equals(userDto.getId()))) {
            return Results.failure(ResponseCode.PHONE_REPEAT.getCode(), ResponseCode.PHONE_REPEAT.getMessage());
        }
//        sysUser = userService.getUserByEmail(userDto.getEmail());
//        if(sysUser != null && !(sysUser.getId().equals(userDto.getId()))){
//            return Results.failure(ResponseCode.EMAIL_REPEAT.getCode(),ResponseCode.EMAIL_REPEAT.getMessage());
//        }
        return userService.updateUser(userDto, roleId);
    }

    /**
     * 删除用户
     *
     * @param userDto 用户dto
     * @return {@link Results}
     */
    @GetMapping("/delete")
    @ResponseBody
    @PreAuthorize("hasAuthority('sys:user:del')")
    @ApiOperation(value = "删除用户信息", notes = "删除用户信息")
    @ApiOperationSupport(author = "柠檬水 cherryok@126.com")
    @ApiImplicitParam(name = "userDto", value = "用户实体类", required = true, dataType = "UserDto")
    @Logger(value = "删除用户",type = 2)
    public Results deleteUser(UserDto userDto) {
        log.info("UserController.deleteUser():param (" + userDto + ")");
        int count = userService.deleteUser(userDto.getId());
        if (count > 0) {
            return Results.success();
        } else {
            return Results.failure();
        }
    }

    /**
     * 找到用户的用户名
     *
     * @param page     页面
     * @param username 用户名
     * @return {@link Results<SysUser>}
     */
    @GetMapping("/findUserByUsername")
    @ResponseBody
    @PreAuthorize("hasAuthority('sys:user:query')")
    @ApiOperationSupport(author = "柠檬水 cherryok@126.com")
    @ApiOperation(value = "模糊查询用户信息", notes = "模糊搜索查询用户信息")//描述
    @ApiImplicitParams({
            @ApiImplicitParam(name = "username",value = "模糊搜索的用户名", required = true),
    })
    @Logger(value = "搜索查询用户",type = 2)
    public Results<SysUser> findUserByUsername(PageTableRequest page,String username) {
        log.info("UserController.getUsersPage():param (page=" + page + "+"+username+")");
        page.countOffset();//计算
        return userService.findUserByUsername(username,page.getOffset(), page.getLimit());
    }

    /**
     * 更新密码
     *
     * @return {@link String}
     */
    @GetMapping("/changePassword")
    @ApiOperation(value = "修改密码", notes = "跳转到用户信息编辑页面")
    @ApiOperationSupport(author = "柠檬水 cherryok@126.com")
    @PreAuthorize("hasAuthority('sys:user:password')")
    @Logger(value = "修改密码",type = 2)
    public String updatePassword() {
        return "user/user-change-password";
    }

    /**
     * 更改密码
     *
     * @param username    用户名
     * @param oldPassword 旧密码
     * @param newPassword 新密码
     * @return {@link Results<SysUser>}
     */
    @PostMapping("/changePassword")
    @ApiOperation(value = "修改密码")
    @ApiOperationSupport(author = "柠檬水 cherryok@126.com")
    @ResponseBody
    public Results<SysUser> changePassword(@Param("username") String username, @Param("oldPassword") String oldPassword, @Param("newPassword") String newPassword) {
        return userService.changePassword(username,oldPassword,newPassword);
    }
}
